package net.sunofbeaches.controller.user;

import com.sun.deploy.cache.Cache;
import com.wf.captcha.ArithmeticCaptcha;
import com.wf.captcha.GifCaptcha;
import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.slf4j.Slf4j;
import net.sunofbeaches.pojo.SobUser;
import net.sunofbeaches.response.ResponseResult;
import net.sunofbeaches.services.IUserService;
import net.sunofbeaches.utils.Constants;
import net.sunofbeaches.utils.RedisUtil;
import net.sunofbeaches.utils.TextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.websocket.server.PathParam;
import java.awt.*;
import java.io.IOException;
import java.util.Random;

@Slf4j
@RestController
@RequestMapping("/user")
public class UserApi {

    @Autowired// 阔以表明引用哪个类
    private IUserService userService;

    /**
     * 初始化管理员账号-init-admin
     */
    @PostMapping("/admin_account")
    public ResponseResult initManagerAccount(@RequestBody SobUser sobUser, HttpServletRequest request) {
        log.info("user name == >" + sobUser.getUserName());
        log.info("password == >" + sobUser.getPassword());
        log.info("email == >" + sobUser.getEmail());
        return userService.initManagerAccount(sobUser, request);
    }

    /**
     * 注册
     *
     * @param sobUser
     * @return
     */
    @PostMapping("/join_in")
    public ResponseResult register(@RequestBody SobUser sobUser,
                                   @RequestParam("email_code") String emailCode,
                                   @RequestParam("captcha_code") String captchaCode,
                                   @RequestParam("captcha_key") String captchaKey,
                                   HttpServletRequest request) {
        // 第一步:检查当前用户名是否已经注册
        // 第二步:检查邮箱格式是否正确
        // 第三步:检查该邮箱是否已经注册
        // 第四步:检查邮箱验证码是否正确
        // 第五步:检查图灵验证码是否正确达到可以注册的条件
        // 第六步:对密码进行加密
        // 第七步:补全数据
        // 包括:注册IP,登录IP,角色,头像,创建时间,更新时间
        // 第八步:保存到数据库中
        // 第九步:返回结果
        return userService.register(sobUser, emailCode, captchaCode, captchaKey, request);
    }

    /**
     * 登录sign-up
     *
     * @param captcha
     * @param sobUser
     * @return
     */
    @PostMapping("/login/{captcha}/{captcha_key}")
    public ResponseResult login(@PathVariable("captcha_key") String captchaKey,
                                @PathVariable("captcha") String captcha,
                                @RequestBody SobUser sobUser,
                                HttpServletRequest request,
                                HttpServletResponse response) {
        return userService.doLogin(captcha, captchaKey, sobUser, request, response);
    }


    /**
     * 获取图灵验证码
     * 有效时长十分钟
     *
     * @return
     */
    @GetMapping("/captcha")
    public void getCaptcha(HttpServletResponse response, @RequestParam("captcha_key") String captchaKey) throws IOException, FontFormatException {
        try {
            userService.createCaptcha(response, captchaKey);
        } catch (Exception e) {
            log.info(e.toString());
        }
    }

    /**
     * 发送邮件email
     * 发送邮箱验证码
     * 使用场景:注册、找回密码、修改邮箱（会输入新的邮箱>
     * 注册(register):如果已经注册过了，就提示说,该邮箱已经注册
     * 找回密码(forget):如果没有注册过,提示该邮箱没有注册
     * 修改邮箱(update）（新的邮箱）:如果已经注册了，提示改邮箱已经注册
     *
     * @param emailAddress
     * @return
     */
    @GetMapping("/verify_code")
    public ResponseResult sendVerifyCode(String type, HttpServletRequest request, @RequestParam("email") String emailAddress) {
        log.info("email == >" + emailAddress);
        return userService.sendEmail(type, request, emailAddress);
    }

    /**
     * 获取作者信息 user-info
     *
     * @return
     */
    @GetMapping("/user_info/{userId}")
    public ResponseResult getUserInfo(@PathVariable("userId") String userId) {
        return userService.getUserInfo(userId);
    }

    /**
     * 修改用户信息 user-info
     * 允许用户修改的内容
     * 1、头像
     * 2、用户名(唯一的)
     * 2.5、签名
     * 3、密码(单独修改)
     * 4、Email(唯一的，单独修改)
     *
     * @param userId
     * @return
     */
    @PutMapping("/user_info/{userId}")
    public ResponseResult updateUserInfo(HttpServletRequest request,
                                         HttpServletResponse response,
                                         @PathVariable("userId") String userId,
                                         @RequestBody SobUser sobUser) {
        return userService.updateUserInfo( userId, sobUser);
    }

    /**
     * 判断邮箱是否重复
     *
     * @param email
     * @return
     */
    @ApiResponses({
            @ApiResponse(code = 2000, message = "表示当前邮箱已经注册了"),
            @ApiResponse(code = 4000, message = "表示当前邮箱已经注册了")
    })
    @GetMapping("/email")
    public ResponseResult checkEmail(@RequestParam("email") String email) {
        return userService.checkEmail(email);
    }

    /**
     * 判断用户名是否重复
     *
     * @param userName
     * @return
     */
    @ApiResponses({
            @ApiResponse(code = 2000, message = "表示用户名已经注册了"),
            @ApiResponse(code = 4000, message = "表示用户名已经注册了")
    })
    @GetMapping("/user_name")
    public ResponseResult checkUserName(@RequestParam("userName") String userName) {
        return userService.checkUserName(userName);
    }

    @DeleteMapping("/{userId}")
    public ResponseResult deleteUser(@PathVariable("userId") String userId) {
        return userService.deleteUserById(userId);
    }

    @PreAuthorize("@permission.adminPermission()")
    @GetMapping("list")
    public ResponseResult listUsers(@RequestParam("page")int page,
                                    @RequestParam("size") int size){
        return userService.listUsers(page,size);
    }

    /**
     * 修改密码password
     * 修改密码
     * 普通做法：通过旧密码对比来更新密码
     * <p>
     * 即可以找回密码，也可以修改密码
     * 发送验证码到邮箱/手机---> 判断验证码是否真确来判断
     * 对应邮箱/手机号码所注册的账号是否属于你。
     * <p>
     * 步骤：
     * 1、用户填写邮箱
     * 2、用户获取验证码type=forget
     * 3、填写验证码
     * 4、填写新的密码
     * 5、提交数据
     * <p>
     * 数据包括：
     * <p>
     * 1、邮箱和新密码
     * 2、验证码
     * <p>
     * 如果验证码正确-->所用邮箱注册的账号就是你的，可以修改密码
     *
     * @param verifyCode
     * @param sobUser
     * @return
     */
    @PutMapping("/password/{verifyCode}")
    public ResponseResult updatePassword(@PathVariable("verifyCode")String verifyCode,
                                         @RequestBody SobUser sobUser){
        return userService.updateUserPassword(verifyCode,sobUser);
    }

    /**
     * 1、必须已经登录了
     * 2、新的邮箱没有注册过
     * <p>
     * 用户的步骤：
     * 1、已经登录
     * 2、输入新的邮箱地址
     * 3、获取验证码 type=update
     * 4、输入验证码
     * 5、提交数据
     * <p>
     * 需要提交的数据
     * 1、新的邮箱地址
     * 2、验证码
     * 3、其他信息我们可以token里获取
     *
     * @return
     */
    @PutMapping("/email")
    public ResponseResult updateEmail(@RequestParam("email") String email,
                                      @RequestParam("verify_code")String verifyCode){
        return userService.updateEmail(email,verifyCode);
    }

    @PutMapping("/logout")
    public ResponseResult logout(){
        return userService.doLogout();
    }
}
